<template>
  <div class="table-page">
    <!-- 搜索区域：条件筛选和查询重置 -->
    <Search
      v-if="showSearch && searchConfig.length"
      ref="searchRef"
      :search-config="searchConfig"
      :label-width="searchLabelWidth"
      @search="handleSearch"
      @reset="handleReset"
    />

    <!-- 表格内容区域：数据展示和分页 -->
    <TableContent
      ref="tableRef"
      :title="title"
      :data="data"
      :columns="columns"
      :loading="loading"
      :table-props="tableProps"
      :show-pagination="showPagination"
      :pagination-config="paginationConfig"
      :actions-width="actionsWidth"
      @selection-change="handleSelectionChange"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    >
      <!-- 批量操作插槽：用于对选中行进行批量操作 -->
      <template #batchActions="{ rows, clear }">
        <slot name="batchActions" v-bind="{ rows, clear }">
          <!-- 默认的批量操作按钮 -->
          <el-button type="danger" link :icon="Delete" @click="handleBatchDelete(rows)">
            批量删除
          </el-button>
          <el-divider direction="vertical" />
          <el-button link :icon="Close" @click="clear">清空</el-button>
        </slot>
      </template>

      <!-- 表格顶部操作插槽：新增按钮等 -->
      <template #tableActions>
        <slot name="tableActions">
          <!-- 默认的新增按钮 -->
          <el-button type="primary" :icon="Plus" @click="handleAdd">
            {{ addTitle || '新增' }}
          </el-button>
        </slot>
      </template>

      <!-- 行操作插槽：用于对单行数据进行操作 -->
      <template #actions="scope">
        <slot name="actions" v-bind="scope">
          <!-- 默认的行操作按钮 -->
          <el-button type="primary" link :icon="Edit" @click="handleEdit(scope.row)">
            编辑
          </el-button>
          <el-button type="danger" link :icon="Delete" @click="handleDelete(scope.row)">
            删除
          </el-button>
        </slot>
      </template>
    </TableContent>

    <!-- 表单抽屉：用于新增和编辑数据 -->
    <form-drawer
      v-if="formConfig"
      v-model="showForm"
      :title="currentData?.id ? editTitle : addTitle"
      :data="currentData"
      :form-config="formConfig"
      :default-form-data="defaultFormData"
      @success="handleFormSuccess"
    />
  </div>
</template>

<script setup>
import { ref, computed } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Delete, Edit, Plus, Close } from '@element-plus/icons-vue'
import Search from '@/components/TablePage/components/Search.vue'
import TableContent from '@/components/TablePage/components/TableContent.vue'
import FormDrawer from '@/components/TablePage/components/FormDrawer.vue'

/**
 * TablePage - 通用表格页面组件
 *
 * 集成了搜索、表格、分页、表单等功能，提供了完整的CRUD操作支持
 * 通过配置化的方式快速构建后台列表页面
 */

/**
 * Props 定义
 */
const props = defineProps({
  /** 页面标题 */
  title: {
    type: String,
    default: '列表',
  },
  /**
   * 搜索区域配置
   * @type {Array<{
   *   field: string,      // 字段名
   *   label: string,      // 标签名
   *   type: string,       // 表单类型
   *   defaultValue?: any, // 默认值
   *   props?: Object      // 组件属性
   * }>}
   */
  searchConfig: {
    type: Array,
    default: () => [],
  },
  /** 搜索表单标签宽度 */
  searchLabelWidth: {
    type: String,
    default: '80px',
  },
  /** 表格数据源 */
  data: {
    type: Array,
    default: () => [],
  },
  /**
   * 表格列配置
   * @type {Array<{
   *   prop: string,       // 字段名
   *   label: string,      // 列标题
   *   width?: number|string, // 列宽度
   *   sortable?: boolean, // 是否可排序
   *   formatter?: Function, // 格式化函数
   *   slot?: string,      // 插槽名称
   * }>}
   */
  columns: {
    type: Array,
    required: true,
  },
  /** 表格属性配置 */
  tableProps: {
    type: Object,
    default: () => ({
      'table-layout': 'fixed',
    }),
  },
  /** 是否显示分页器 */
  showPagination: {
    type: Boolean,
    default: true,
  },
  /**
   * 分页配置
   * @type {Object}
   */
  paginationConfig: {
    type: Object,
    default: () => ({
      total: 0,
      currentPage: 1,
      pageSize: 10,
      pageSizes: [10, 20, 30, 50],
    }),
  },
  /** 表格加载状态 */
  loading: {
    type: Boolean,
    default: false,
  },
  /** 操作列宽度 */
  actionsWidth: {
    type: [Number, String],
    default: 150,
  },
  /**
   * 表单字段配置
   * @type {Array<{
   *   field: string,      // 字段名
   *   label: string,      // 标签名
   *   type: string,       // 表单类型
   *   rules?: Array,      // 验证规则
   *   defaultValue?: any, // 默认值
   *   props?: Object      // 组件属性
   * }>}
   */
  formConfig: {
    type: Array,
    default: null,
  },
  /** 表单默认值 */
  defaultFormData: {
    type: Object,
    default: () => ({}),
  },
  /** 新增操作标题 */
  addTitle: {
    type: String,
    default: '新增',
  },
  /** 编辑操作标题 */
  editTitle: {
    type: String,
    default: '编辑',
  },
  /**
   * 删除确认文案
   * @type {String|Function} 当为函数时接收行数据作为参数
   */
  deleteConfirm: {
    type: [String, Function],
    default: '确定要删除该数据吗？',
  },
  /**
   * 批量删除确认文案
   * @type {String|Function} 当为函数时接收选中行数据作为参数
   */
  batchDeleteConfirm: {
    type: [String, Function],
    default: (rows) => `确定要删除选中的${rows.length}条数据吗？`,
  },
  /** 是否显示序号列 */
  showIndex: {
    type: Boolean,
    default: true,
  },
  /** 是否显示选择列 */
  showSelection: {
    type: Boolean,
    default: true,
  },
  /** 是否显示操作列 */
  showActions: {
    type: Boolean,
    default: true,
  },
  /** 操作列标题 */
  actionsLabel: {
    type: String,
    default: '操作',
  },
  /** 是否显示搜索区域 */
  showSearch: {
    type: Boolean,
    default: true,
  },
  /** 是否显示表格顶部操作区 */
  showTableActions: {
    type: Boolean,
    default: true,
  },
  /** 是否显示批量操作区 */
  showBatchActions: {
    type: Boolean,
    default: true,
  },
})

/**
 * Emits 定义 - 组件事件
 */
const emit = defineEmits([
  'search', // 搜索事件
  'reset', // 重置事件
  'selection-change', // 选择变化事件
  'size-change', // 分页大小变化事件
  'current-change', // 当前页变化事件
  'add', // 新增事件
  'edit', // 编辑事件
  'delete', // 删除事件
  'batch-delete', // 批量删除事件
])

/**
 * 组件引用
 */
const searchRef = ref(null) // 搜索组件引用
const tableRef = ref(null) // 表格组件引用

/**
 * 搜索相关方法
 */
// 处理搜索
const handleSearch = (params) => {
  emit('search', params)
}

// 处理重置
const handleReset = () => {
  emit('reset')
}

/**
 * 分页相关方法
 */
// 处理选择变化
const handleSelectionChange = (rows) => {
  emit('selection-change', rows)
}

// 处理每页条数变化
const handleSizeChange = (val) => {
  emit('size-change', val)
}

// 处理页码变化
const handleCurrentChange = (val) => {
  emit('current-change', val)
}

/**
 * 表单相关状态
 */
const showForm = ref(false) // 是否显示表单抽屉
const currentData = ref(null) // 当前操作的数据对象

/**
 * CRUD操作方法
 */
// 处理新增操作
const handleAdd = () => {
  if (props.formConfig) {
    // 如果有表单配置，打开表单抽屉
    currentData.value = null
    showForm.value = true
  } else {
    // 如果没有表单配置，直接触发 add 事件
    emit('add')
  }
}

// 处理编辑操作
const handleEdit = (row) => {
  if (!props.formConfig) {
    ElMessage.warning('未配置表单')
    return
  }
  currentData.value = { ...row } // 创建数据副本，避免直接修改原始数据
  showForm.value = true
}

// 处理删除操作
const handleDelete = (row) => {
  ElMessageBox.confirm(getDeleteConfirmText(row), '删除确认', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
  })
    .then(() => {
      emit('delete', row)
    })
    .catch(() => {
      // 取消删除，不执行任何操作
    })
}

// 处理批量删除操作
const handleBatchDelete = (rows) => {
  if (!rows.length) {
    ElMessage.warning('请选择要删除的数据')
    return
  }

  ElMessageBox.confirm(getBatchDeleteConfirmText(rows), '批量删除确认', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
  })
    .then(() => {
      emit('batch-delete', rows)
      tableRef.value?.clearSelection() // 清空选择
    })
    .catch(() => {
      // 取消删除，不执行任何操作
    })
}

// 处理表单提交成功
const handleFormSuccess = (data) => {
  // 根据数据是否有ID判断是新增还是编辑操作
  const isEdit = Boolean(data.id)
  emit(isEdit ? 'edit' : 'add', data)
  showForm.value = false // 关闭表单抽屉
}

/**
 * 计算属性
 */
// 计算表格列配置
const tableColumns = computed(() => {
  const columns = []

  // 添加序号列
  if (props.showIndex) {
    columns.push({
      type: 'index',
      label: '序号',
      width: 60,
      align: 'center',
    })
  }

  // 添加选择列
  if (props.showSelection) {
    columns.push({
      type: 'selection',
      width: 40,
      align: 'center',
    })
  }

  // 添加数据列
  columns.push(...props.columns)

  // 添加操作列
  if (props.showActions) {
    columns.push({
      label: props.actionsLabel,
      width: props.actionsWidth,
      fixed: 'right',
      slot: 'actions',
    })
  }

  return columns
})

/**
 * 辅助函数
 */
// 获取删除确认文案
const getDeleteConfirmText = (row) => {
  if (typeof props.deleteConfirm === 'function') {
    return props.deleteConfirm(row)
  }
  // 自动从标题中提取实体类型
  const type = props.title.slice(0, -2) || '数据'
  return `确定要删除该${type}吗？`
}

// 获取批量删除确认文案
const getBatchDeleteConfirmText = (rows) => {
  if (typeof props.batchDeleteConfirm === 'function') {
    return props.batchDeleteConfirm(rows)
  }
  // 自动从标题中提取实体类型
  const type = props.title.slice(0, -2) || '数据'
  return `确定要删除选中的${rows.length}条${type}吗？`
}

/**
 * 暴露方法和属性
 */
defineExpose({
  // CRUD操作方法
  handleAdd,
  handleEdit,
  handleDelete,
  handleBatchDelete,
  // 表格操作方法
  clearSelection: () => tableRef.value?.clearSelection(),
  // 分页相关
  pagination: () => tableRef.value?.pagination,
  // 搜索相关
  refresh: handleSearch,
  reset: handleReset,
})
</script>

<style lang="scss" scoped>
// 导入主题变量和混合器
@use '@/assets/styles/theme/base.scss' as *;
@use '@/assets/styles/mixins.scss' as *;

/**
 * 表格页面组件样式
 */
.table-page {
  // 基础布局
  height: 100%;
  display: flex;
  flex-direction: column;
  gap: 16px;
  box-sizing: border-box;
  background-color: $bg-light;
  min-width: 850px;

  // 卡片通用样式
  :deep(.el-card) {
    border: none;
    border-radius: $radius-large;
    box-shadow: $shadow-light;
    @include transition(box-shadow);

    &:hover {
      box-shadow: $shadow-base;
    }
  }

  // 响应式适配
  @include respond-to('sm') {
    padding: 0;
    min-width: auto;
    gap: 12px;
  }
}
</style>
